// 界面 UI 其实就是数据的抽象，所以就是使用特定的数据结构将它渲染成界面
// const TextComponentProps = {
//   text: 'hello',
//   color: '#fff'
// }

// const propsMap = {
//   text: {
//     component: 'input'
//   },
//   color: {
//     component: 'color-picker'
//   }
// }
import { VNode, h } from 'vue'
import { AllFormProps } from '@/stores/editor'

// export interface PropToForm {
//   component: string
//   subComponent?: string
//   extraProps?: { [key: string]: any }
//   text?: string
//   options?: { props: { label?: any; value?: any }; text?: string | VNode }[]
//   initialTransform?: (v: any) => any
//   afterTransform?: (v: any) => any
//   valueProp?: string
//   eventName?: string
//   events?: { [key: string]: (e: any) => void }
//   value?: string
// }

// PropToForm: 组件和form对应关系的结构
export interface PropToForm {
  component: string // 渲染表单对应的组件
  subComponent?: string // 渲染表单对应的子组件；如果有的话
  extraProps?: { [key: string]: any } // 渲染表单组件的额外参数
  text?: string // 表单组件标题
  valueProp?: string // 自定义动态绑定value的参数；:[item.valueProp]="item.value"； 在element上大多数都是 v-model 所以暂时无用
  options?: { props: { label?: any; value?: any }; text?: string | VNode }[] // 渲染表单子组件需要的参数，label和value按组件需要填充
  initialTransform?: (v: any) => any // 原始值转化成表单组件需要值的方法
  afterTransform?: (v: any) => any // 表单组件值转化成原始值的方法
  eventName?: string // 自定义表单组件事件名称；默认 change
}

export type PropsToForms = {
  [p in keyof AllFormProps]?: PropToForm
}

const fontFamilyArr = [
  { value: '"SimSun", "STSong"', label: '宋体' },
  { value: '"SimHei", "STHeiti"', label: '黑体' },
  { value: '"KaiTi", "STKaiti"', label: '楷体' },
  { value: '"FangSong", "STFangsong"', label: '仿宋' }
]

const fontFamilyOptions = fontFamilyArr.map(font => {
  return {
    props: {
      value: font.value,
      label: font.label
    },
    text: h('span', { style: { fontFamily: font.value } }, font.label)
  }
})

// const defaultInput = {
//   component: 'el-input',
//   eventName: 'input',
//   initialTransform: (v: any) => v,
//   afterTransform: (e: any) => e
// }

const pxToNumberTransform = {
  initialTransform: (v: string) => (v ? parseInt(v) : 0),
  afterTransform: (e: number) => (e ? `${e}px` : '')
}

export const mapPropsToForms: PropsToForms = {
  // textComponentProps
  text: {
    text: '文本',
    component: 'el-input',
    extraProps: {
      type: 'textarea',
      rows: 3
    },
    eventName: 'input'
  },
  fontSize: {
    text: '字号',
    component: 'el-input-number',
    ...pxToNumberTransform
    // initialTransform: (v: string) => parseInt(v),
    // afterTransform: (e: number) => (e ? `${e}px` : '')
  },
  lineHeight: {
    text: '行高',
    component: 'el-slider',
    extraProps: {
      min: 0,
      max: 3,
      step: 0.1
    },
    initialTransform: (v: string) => parseFloat(v),
    afterTransform: (e: number) => e.toString(),
    eventName: 'input'
  },
  textAlign: {
    component: 'el-radio-group',
    subComponent: 'el-radio-button',
    text: '对齐',
    options: [
      { props: { label: 'left' }, text: '左' },
      { props: { label: 'center' }, text: '中' },
      { props: { label: 'right' }, text: '右' }
    ]
  },
  fontFamily: {
    component: 'el-select',
    subComponent: 'el-option',
    text: '字体',
    options: [{ props: { value: '', label: '无' } }, ...fontFamilyOptions]
  },
  fontWeight: {
    component: 'icon-switch',
    initialTransform: (v: string) => v === 'bold',
    afterTransform: (e: boolean) => (e ? 'bold' : 'normal'),
    extraProps: { iconName: 'bold', tip: '加粗' }
  },
  fontStyle: {
    component: 'icon-switch',
    initialTransform: (v: string) => v === 'italic',
    afterTransform: (e: boolean) => (e ? 'italic' : 'normal'),
    extraProps: { iconName: 'italic', tip: '斜体' }
  },
  textDecoration: {
    component: 'icon-switch',
    initialTransform: (v: string) => v === 'underline',
    afterTransform: (e: boolean) => (e ? 'underline' : 'none'),
    extraProps: { iconName: 'underline', tip: '下划线' }
  },
  color: {
    component: 'color-picker',
    text: '字体颜色'
  },
  backgroundColor: {
    component: 'color-picker',
    text: '背景颜色'
  },
  // imageComponentProps
  src: {
    component: 'image-processer'
  },

  // commonComponentProps - 尺寸
  width: {
    text: '宽度',
    component: 'el-input-number',
    ...pxToNumberTransform
  },
  height: {
    text: '高度',
    component: 'el-input-number',
    ...pxToNumberTransform
  },
  paddingLeft: {
    text: '左边距',
    component: 'el-input-number',
    ...pxToNumberTransform
  },
  paddingRight: {
    text: '右边距',
    component: 'el-input-number',
    ...pxToNumberTransform
  },
  paddingTop: {
    text: '上边距',
    component: 'el-input-number',
    ...pxToNumberTransform
  },
  paddingBottom: {
    text: '下边距',
    component: 'el-input-number',
    ...pxToNumberTransform
  },

  // commonComponentProps - 边框
  borderStyle: {
    component: 'el-select',
    subComponent: 'el-option',
    text: '边框类型',
    options: [
      { props: { value: 'none', label: '无' } },
      { props: { value: 'solid', label: '实线' } },
      { props: { value: 'dashed', label: '破折线' } },
      { props: { value: 'dotted', label: '点状线' } }
    ]
  },
  borderColor: {
    component: 'color-picker',
    text: '边框颜色'
  },
  borderWidth: {
    component: 'el-slider',
    text: '边框宽度',
    extraProps: { min: 0, max: 20 },
    eventName: 'input',
    ...pxToNumberTransform
  },
  borderRadius: {
    component: 'el-slider',
    text: '边框圆角',
    extraProps: { min: 0, max: 200 },
    eventName: 'input',
    ...pxToNumberTransform
  },

  // commonComponentProps - 阴影与透明度
  opacity: {
    component: 'el-slider',
    text: '透明度',
    initialTransform: (v: number) => (v ? v * 100 : 100),
    afterTransform: (e: number) => e / 100,
    extraProps: { min: 0, max: 100, reverse: true },
    eventName: 'input'
  },
  boxShadow: {
    component: 'shadow-picker'
  },

  // commonComponentProps - 位置
  left: {
    text: 'X轴坐标',
    component: 'el-input-number',
    ...pxToNumberTransform
  },
  top: {
    text: 'Y轴坐标',
    component: 'el-input-number',
    ...pxToNumberTransform
  },
  // commonComponentProps - 事件功能
  // actions
  actionType: {
    component: 'el-select',
    subComponent: 'el-option',
    text: '点击',
    options: [{ props: { value: '', label: '无' } }, { props: { value: 'to', label: '跳转到 URL' } }]
  },
  url: {
    component: 'el-input',
    eventName: 'input',
    // afterTransform: (e: any) => e.target.value,
    text: '链接'
  },
  backgroundImage: {
    component: 'background-processer',
    // 初始化时将图片地址解析, 因为组件内部只需要图片路径
    // url("Nx-Dp3.png") => Nx-Dp3.png
    initialTransform: (v: string) => {
      if (v) {
        // https://regexr.com/ 验证正则；匹配 ("/' 图片路径 "/')
        const reg = /\(["'](.+)["']\)/g
        const matches = reg.exec(v)
        if (matches && matches.length > 1) {
          // console.log(matches)
          return matches[1]
        } else {
          return ''
        }
      } else {
        return ''
      }
    },
    // 对图片处理完成后转换成 css 背景图片样式：url("Nx-Dp3.png")
    // afterTransform: (e: string) => (e ? `url('${e}')` : '')
    afterTransform: (e: any) => {
      const result = { url: '', height: '560px' }
      if (e) {
        const { url, height } = e
        result.url = url ? `url('${url}')` : ''
        result.height = height ? `${height}px` : '560px'
      }
      return result
    }
  }
}
